package cn.mrcode.wxsdk.web.common.ticket.lifeCycle.single;


import cn.mrcode.wxsdk.core.context.SdkContexts;
import cn.mrcode.wxsdk.core.dialogue.common.LogUtil;
import cn.mrcode.wxsdk.core.dialogue.common.exception.ReqException;
import cn.mrcode.wxsdk.core.dialogue.common.exception.WxException;
import cn.mrcode.wxsdk.core.dialogue.common.util.DateUtil;
import cn.mrcode.wxsdk.web.common.ticket.TicketApi;
import cn.mrcode.wxsdk.web.protocol.base.JsApiTicketInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author zhuqiang
 * @version V1.0
 * @Description: JsApiTicket维护
 * @date 2015/9/8 9:03
 */
public class TicketTask implements Runnable{
    private static Logger log = LoggerFactory.getLogger(TicketTask.class);
    private ConcurrentHashMap<String, JsApiTicketInfo> map;
    private boolean timeOutDestroy = false;  //超时功能是否打开标志
    private int time; //超时时间

    public TicketTask(ConcurrentHashMap<String, JsApiTicketInfo> map) {
        this.map = map;
    }

    /**
     * 打开 超时指定时间不使用accessToken则销毁该token的缓存对象
     * @param flag 超时功能 标志
     * @param time 超时时间，单位为 分钟
     */
    public void openTimeOutDestroy(boolean flag,int time){
        this.timeOutDestroy = flag;
        this.time = time;
    }

    @Override
    public void run() {
        for (Map.Entry<String, JsApiTicketInfo> ent : map.entrySet()) {
            String key = ent.getKey();
            JsApiTicketInfo value = ent.getValue();

            if (timeOutDestroy) {  //超过了设定的未使用时间，则把token对象移除
                Date overtime = DateUtil.computingTime(value.getLastUseTime(), Calendar.MINUTE, time);
                if (overtime.getTime() < new Date().getTime()) { //已经超时了
                    map.remove(key);
                    log.info(value.getAppID() + "该微信公众号的JsApiTicketInfo已经被移除了（由于太久未被使用）");
                    continue;
                }
            }

            Date overtime = DateUtil.computingTime(value.getCreateTime(), Calendar.MINUTE, SdkContexts.getConfigContext().JSAPI_TICKET_TIME_OUT);
            if (overtime.getTime() < new Date().getTime()) { //已经超时了
                String appID = value.getAppID();
                try {
                    value = TicketApi.getJsApiTicketInfo(appID, value.getAppSecret());
                } catch (ReqException e) {
                    log.error(LogUtil.fromateLog(e));
                    throw new RuntimeException(e.getMessage());
                } catch (WxException e) {
                    log.error(LogUtil.fromateLog(e));
                    throw new RuntimeException(e.getMessage());
                }
                map.put(appID, value);
                log.info(appID + "该微信公众号的JsApiTicketInfo已经更新了（由于已经快超时了）");
            }
        }
    }
}
